package ch15
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;

	import utils.Ball;

	/**
	 * ActionScript 透视(解决Perspective1中当zpos<=fl时候会出现问题的情况)
	 * @author sjp
	 *
	 */
	public class Perspective2 extends Sprite
	{
		private var ball:Ball;
		//xpos, ypos, zpos 代表 3D 坐标
		private var xpos:Number = 0;
		private var ypos:Number = 0;
		private var zpos:Number = 0;
		//fl [焦距：focal length]，相当于人眼的电脑屏幕的距离
		private var fl:Number = 250;
		//事实上，屏幕上的位置是相对于消失点的位置而定的
		//消失点（vanishing point）vpX, vpY
		private var vpX:Number = stage.stageWidth / 2;
		private var vpY:Number = stage.stageHeight / 2;

		public function Perspective2()
		{
			init();
		}

		private function init():void
		{
			ball = new Ball();
			addChild(ball);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}

		private function onEnterFrame(event:Event):void
		{
			if (zpos > -fl)
			{
				xpos = mouseX - vpX;
				ypos = mouseY - vpY;
				//公式:scale = fl / (fl + z)
				/**
				 * 用数字解释一下，当 zpos 等于–fl 时，公式从 scale = fl / (fl + zpos) 变为 scale = fl / 0。
				 * 在许多语言中，除以 0 会报错。在 Flash 中，将得到一个无限大的值。
				 * 如果再将 zpos 减小，那么就是用 fl 除以一个负数。scale 变为负数，这就是为什么小球会颠倒并反向运动的原因。
				 * */
				var scale:Number = fl / (fl + zpos);
				ball.scaleX = ball.scaleY = scale;
				/**
				 * 屏幕上的位置是相对于消失点的位置而定的.
				 * 当 scale 变得很小时，小球将汇集到消失点上。
				 * */
				ball.x = vpX + xpos * scale;
				ball.y = vpY + ypos * scale;
				ball.visible = true;
			}
			else
			{
				ball.visible = false;
			}

		}

		private function onKeyDown(event:KeyboardEvent):void
		{
			if (event.keyCode == Keyboard.UP)
			{
				zpos += 5;
			}
			else if (event.keyCode == Keyboard.DOWN)
			{
				zpos -= 5;
			}
		}
	}
}